package com.zhouchj.elasticsearch;

import com.zhouchj.elasticsearch.index.EsIndexOperate;
import com.zhouchj.elasticsearch.query.EsLambdaQueryChainWrapper;
import com.zhouchj.elasticsearch.update.EsLambdaUpdateChainWrapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.elasticsearch.core.mapping.IndexCoordinates;

import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.Objects;

/**
 * es Service 可以直接继承此类获取es相关能力
 *
 * @author zhouchj
 * @date 2023/9/4
 */
@SuppressWarnings("unchecked")
public class EsServiceImpl<T> {

    private final Class<T> clazz = currentClass();

    @Autowired
    private EsToolkitFactory esToolkitFactory;

    private IndexCoordinates indexCoordinates;

    protected void index(String... indexNames) {
        this.indexCoordinates = IndexCoordinates.of(indexNames);
    }


    /**
     * lambda查询
     *
     * @return EsLambdaQueryChainWrapper
     */
    protected EsLambdaQueryChainWrapper<T> lambdaQuery() {
        if (Objects.isNull(indexCoordinates)) {
            return esToolkitFactory.lambdaQuery(clazz);
        }
        return esToolkitFactory.lambdaQuery(indexCoordinates, clazz);
    }

    /**
     * lambda查询
     *
     * @param indexName 索引名称
     * @return EsLambdaQueryChainWrapper
     */
    protected EsLambdaQueryChainWrapper<T> lambdaQuery(String indexName) {
        return esToolkitFactory.lambdaQuery(indexName, clazz);
    }


    /**
     * lambda更新
     *
     * @return EsLambdaUpdateChainWrapper
     */
    protected EsLambdaUpdateChainWrapper<T> lambdaUpdate() {
        if (Objects.isNull(indexCoordinates)) {
            return esToolkitFactory.lambdaUpdate(clazz);
        }
        return esToolkitFactory.lambdaUpdate(indexCoordinates, clazz);
    }


    /**
     * lambda更新
     *
     * @param indexName 索引名称
     * @return EsLambdaUpdateChainWrapper
     */
    protected EsLambdaUpdateChainWrapper<T> lambdaUpdate(String indexName) {
        return esToolkitFactory.lambdaUpdate(indexName, clazz);
    }


    /**
     * es索引操作
     *
     * @return EsIndexOperate
     */
    protected EsIndexOperate<T> indexOperate() {
        if (Objects.isNull(indexCoordinates)) {
            return esToolkitFactory.indexOperate(clazz);
        }
        return esToolkitFactory.indexOperate(indexCoordinates, clazz);
    }

    /**
     * es索引操作
     *
     * @param indexName 索引名称
     * @return EsIndexOperate
     */
    protected EsIndexOperate<T> indexOperate(String indexName) {
        return esToolkitFactory.indexOperate(indexName, clazz);
    }


    /**
     * 获取当前类(EsServiceImpl)的泛型
     *
     * @return class
     */
    private Class<T> currentClass() {
        Type genericSuperclass = this.getClass().getGenericSuperclass();
        if (genericSuperclass instanceof ParameterizedType) {
            ParameterizedType parameterizedType = (ParameterizedType) genericSuperclass;
            Type[] actualTypeArguments = parameterizedType.getActualTypeArguments();

            if (actualTypeArguments.length > 0) {
                // 获取泛型参数类型的 Class 对象
                return (Class<T>) actualTypeArguments[0];
            }
        }
        throw new RuntimeException("获取class失败");
    }
}
